home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 015 / ega43.arc / EPSON.ASM < prev    next >
Encoding:
Assembly Source File  |  1986-07-27  |  17.8 KB  |  512 lines

  1.          page  60,132
  2.          title Graphics Module for Print Screen with the EGA
  3. Epson    segment para public 'code'
  4.          assume cs:Epson,ds:Epson,es:Epson
  5.  
  6. comment #
  7.  
  8. This routine is for public domain for those of you who bought an
  9. EGA and enhanced monitor and determined that you could no longer
  10. do a Shf_Prt_Scn in mode 10h (16).  If you have an IBM compatible
  11. and an Epson FX series printer then this routine will replace the
  12. Graphics.com routine. I also have routines for Radio Shack DMP 
  13. printers with 8 pins (but only 7 usable for graphics) and for HP
  14. LaserJet printers when used with an EGA. Enjoy...
  15.  
  16. Dr. R. Brooks Van Horn, Jr.
  17. 701 Fall Place
  18. Herndon, VA. 22070
  19.  
  20. #
  21.          org 100h 
  22.          jmp   Setup
  23.  
  24. Mlen     db    'EGA Graphics Ver 1.0'
  25. Cmp_Str  dw    $-mlen
  26.  
  27. ;        normal int 5 entry point
  28.  
  29. Begin:   pushf               ; enable further interrupts
  30.          push  ax
  31.          push  bx
  32.          push  bp
  33.          push  di
  34.          push  si
  35.          mov   ah,15         ; setup a function call to dos to
  36.          int   10h           ; get the video mode
  37.          and   ax,007fh      ; mask off unwanted data
  38.          mov   cs:[Mode],ax  ; and save it for future use
  39.          cmp   al,7          ; is this a mono card?
  40.          jz    Out           ; yes, exit - when in text mode
  41.          cmp   al,3          ; see if we are in the graphics mode?
  42.          jg    cont          ; yes, go around using dos
  43. Out:     pop   si            ; restore the registers saved
  44.          pop   di
  45.          pop   bp
  46.          pop   bx
  47.          pop   ax
  48.          popf
  49. ;-----   jump far to Dos
  50.          db    0EAh          ; jump far segment to Print
  51. dos      dw    0             ; offset of jump
  52. dos2     dw    0             ; segment of jump
  53.  
  54. Cont:    push  cx            ; and save all the registers
  55.          push  dx
  56.          push  ds
  57.          push  es
  58.          push  cs            ; now put code seg register into
  59.          pop   es            ; the extra segment register
  60.          xor   ax,ax
  61.          mov   ds,ax
  62.          inc   al            ; see if we are already being done
  63.          mov   al,Byte Ptr ds:[500h] ; get the current mode and also set it
  64.          or    al,al
  65.          jnz   Getout        ; if 550h was not zero then exit
  66.          push  cs
  67.          pop   ds
  68.          xchg  al,Byte Ptr cs:switch
  69.          or    al,al
  70.          jnz   GetOut
  71.          sti
  72.          mov   cs:[sp_save],sp
  73.          jmp   Process
  74.  
  75. Return:  mov   si,Offset Restore
  76.          mov   cl,cs:[si]    ; get number of bytes to print
  77.          xor   ch,ch
  78.          inc   si
  79.          call  Tabptr        ; restore printer to original state
  80. Exit:    mov   sp,cs:[sp_save]
  81.          xor   ax,ax
  82.          mov   Byte Ptr cs:switch,al ; set value to zero
  83. Getout:  pop   es            ; restore registers and exit
  84.          pop   ds
  85.          pop   dx
  86.          pop   cx
  87.          pop   si
  88.          pop   di
  89.          pop   bp
  90.          pop   bx
  91.          pop   ax
  92.          popf
  93.          sti
  94.          iret                ; bye...............
  95.  
  96. ;--------------------------------------------------------------------
  97. ;              Epson FX Printer with IBM-PC
  98. ;--------------------------------------------------------------------
  99. Line_Sp  db    3,27,51,24    ; Control Codes for 24/216" line spacing
  100. Set_Graf db    4,27,76       ; Cntrl Code for each graphics line printed
  101. Col_2_Do dw    0             ; last column number  to be printed
  102. Restore  db    2,27,48,12    ; change count to 3 if you want a form feed
  103.  
  104. Line_Buf db    960 dup (?)   ; line buffer
  105. Eight    dw    8
  106. Four     dw    4
  107. Switch   db    0
  108. Sp_Save  dw    0
  109. Mode     dw    0             ; Current Video Mode
  110. Rows     dw    0             ; Number of rows for this mode
  111. Cols     dw    0             ; Number of columns for this mode
  112.  
  113. ;      Modes =   4   5   6   7   8   9   A   B   C   D   E   F  10
  114. Col_Mode dw    320,320,640,  0,  0,320,640,  0,720,320,640,640,640
  115. Row_Mode dw    200,200,200,  0,  0,200,200,  0,348,200,200,350,350
  116.  
  117. ;--------------------------------------------------------------------
  118.  
  119. ;        Print a Table of Control Values
  120. ;        ===============================
  121. ;
  122. Tabptr:  mov   al,cs:[si]
  123.          call  Printer
  124.          inc   si
  125.          loop  Tabptr
  126.          nop
  127.          ret
  128. ;
  129. ;        Send an alarm bell sound
  130. ;        ========================
  131. ;
  132. Bell:    mov   al,7
  133.          mov   ah,14
  134.          int   10h
  135.          ret
  136.  
  137. ;        Send the character in AL to the printer
  138. ;        =======================================
  139. ;
  140. Printer: push  dx
  141.          sub   dx,dx
  142.          xor   ah,ah
  143.          int   17h
  144.          pop   dx
  145.          test  ah,25h
  146.          jnz   Error
  147.          ret      
  148. ;
  149. ;        Error returns on printer commands
  150. ;        =================================
  151. Error:   call  Bell
  152.          call  Bell
  153.          jmp   Exit         
  154. ;
  155. ;        Send a form feed to the Printer
  156. ;        ===============================
  157. ;
  158. Cr_Lf:   push  dx
  159.          sub   dx,dx
  160.          mov   ax,0dh
  161.          int   17h
  162.          mov   ax,0ah
  163.          int   17h
  164.          pop   dx
  165.          test  ah,25h
  166.          jnz   Error
  167.          ret
  168.  
  169. ;---------------------------------------------------------------------
  170. ;                                                                    l
  171. ;                  Graphics Processing Section                       l
  172. ;                                                                    l
  173. ;---------------------------------------------------------------------
  174.  
  175. Process: mov   bp,cs:[Mode]
  176.          sub   bp,4
  177.          sal   bp,1
  178.  
  179.          mov   ax,cs:Row_Mode[bp]   ; save rows-1 and cols-1
  180.          dec   ax
  181.          mov   cs:Rows,ax
  182.          mov   ax,cs:Col_Mode[bp]
  183.          dec   ax
  184.          mov   cs:Cols,ax
  185.  
  186.          mov   ah,1             ; initialize the printer
  187.          xor   dx,dx
  188.          int   17h
  189.  
  190.          mov   si,Offset cs:Line_Sp ; setup for correct interline spacing
  191.          mov   cl,cs:[si]       ; get length
  192.          xor   ch,ch
  193.          inc   si
  194.          call  TabPtr
  195.          
  196.          mov   ax,cs:[Cols]     ; decide to do graphics by row or column mode
  197.          cmp   ax,320
  198.          jg    By_Rows
  199.          jmp   By_Cols
  200.  
  201. ;--------------------------------------------------------------------
  202. ;         for By_Rows calls we have usually 640 x 200 type, so do 200
  203. ;         across and 640 down the page.  This means that we can only 
  204. ;         single dot to get lines to connect on the printer paper.
  205. ;--------------------------------------------------------------------
  206.  
  207. By_Rows: mov   cx,0          ; start the column index at zero
  208.  
  209. Br_Strt: push  cx            ; save the current column index
  210.          mov   dx,cs:[Rows]  ; initialize the row count to max
  211.          mov   bh,Byte Ptr cs:[Eight]
  212.          xor   si,si         ; max characters to print
  213.          mov   cs:[Col_2_Do],si
  214.          mov   di,Offset cs:Line_Buf
  215.          xor   bl,bl
  216.  
  217. ;        do for a count of 'Eight'
  218.  
  219. Br_Cont: call  Read          ; read the next dot at (row,col)
  220.          and   al,07fh       ; check if any thing is there
  221.          jz    Br_Fill       ; and skip if nothing there
  222.          mov   al,1          ; else fill the byte 
  223. Br_Fill: shl   bl,1          ; move reg left one bit 
  224.          or    bl,al         ; and or in the next value
  225.          inc   cx            ; increment the column count
  226.          dec   bh            ; and the loop index
  227.          jnz   Br_Cont       ; continue loop for 8 times
  228.  
  229. ;        undo
  230.  
  231.          add   si,2          ; add two to the column counter
  232.          mov   Byte Ptr cs:[di],bl ; save filled byte
  233.          mov   Byte Ptr cs:[di+1],bl ; twice for filling
  234.          cmp   cs:[Rows],199 ; check for less than 200 rows
  235.          jg    Br_Two
  236.          mov   Byte Ptr cs:[di+2],bl ; and 3 times for low resolution
  237.          inc   di
  238.          inc   si
  239. Br_Two:  add   di,2          ; up the buffer ptr
  240.          or    bl,bl         ; do we have anything to print?
  241.          jz    Br_Skp        ; no, skip
  242.  
  243.          mov   cs:[Col_2_Do],si ; save index
  244.  
  245. Br_Skp:  mov   bh,Byte Ptr cs:[Eight] ; set loop for 8 more cols per row
  246.          dec   dx            ; delete one from the row index
  247.          pop   cx            ; restore the column count
  248.          push  cx            ; and save it again for this row
  249.          cmp   dx,0          ; and test to see if we are finished
  250.          jge   Br_Cont       ; loop
  251.  
  252.          mov   cx,cs:[Col_2_Do] ; get the number of bytes to print
  253.          or    cx,cx
  254.          jz    Br_NoP        ; skip if didn't get anything
  255.  
  256.          push  cx            ; save number to do
  257.          mov   si,Offset cs:Set_Graf ; setup for graphics
  258.          mov   cl,cs:[si]    ; get length
  259.          xor   ch,ch
  260.          inc   si            ; point past length field
  261.          call  TabPtr        ; perform the setup
  262.          pop   cx            ; now get the real characters to do
  263.          mov   si,Offset cs:Line_Buf ; get print line pointer
  264.          call  TabPtr        ; and print the line
  265.  
  266. Br_NoP:  call  Cr_Lf         ; do carriage return and line feed at end
  267.  
  268.          pop   cx
  269.          add   cx,cs:[Eight] ; add 8 to column count
  270.          cmp   cx,cs:[Cols]  ; compare to max to do
  271.  
  272.          jg    Br_Ret
  273.          jmp   Br_Strt       ; continue until fini
  274.  
  275. Br_Ret:  jmp   Return        ; restore printer and exit
  276.  
  277. ;--------------------------------------------------------------------
  278. ;         for By_Cols calls we have usually 320 x 200 type, so do 320
  279. ;         across and 200 down the page.  This means that we must double
  280. ;         dot to get lines to connect on the printer paper.
  281. ;--------------------------------------------------------------------
  282.  
  283. By_Cols: mov   dx,0          ; start the row index at zero
  284.  
  285. ;        for each row do all the columns
  286. Bc_Strt: push  dx            ; save the current row index
  287.          mov   cx,0          ; initialize the col count to start
  288.          mov   bh,Byte Ptr cs:[Four]
  289.          xor   si,si         ; max characters to print
  290.          mov   cs:[Col_2_Do],si
  291.          mov   di,Offset cs:Line_Buf
  292.  
  293. ;        for each column in the row, do
  294. Bc_Cont: call  Read          ; read the next dot at (row,col)
  295.          and   al,07fh       ; check if any thing is there
  296.          jz    Bc_Fill       ; and skip if nothing there
  297.          mov   al,3          ; else fill the byte from the bottom
  298. Bc_Fill: shl   bl,1          ; move reg left one bit 
  299.          shl   bl,1          ; and repeat
  300.          or    bl,al         ; and 'or' in the next value
  301.          inc   dx            ; increment the row count
  302.          dec   bh            ; and the loop index
  303.          jnz   Bc_Cont       ; continue loop for 4 times
  304.  
  305.          add   si,3          ; add three to the column counter
  306.          mov   Byte Ptr cs:[di],bl ; save filled byte
  307.          mov   Byte Ptr cs:[di+1],bl ; twice for filling
  308.          mov   Byte Ptr cs:[di+2],bl ; and three times for a lady
  309.          add   di,3          ; up the buffer ptr
  310.          or    bl,bl         ; see if anything is there
  311.          jz    Bc_Skp        ; skip if we have nothing to plot
  312.  
  313.          mov   cs:[Col_2_Do],si ; save index
  314.  
  315. Bc_Skp:  mov   bh,Byte Ptr cs:[Four] ; set loop for 8 more cols per row
  316.          inc   cx            ; add one to the col index
  317.          pop   dx            ; restore the row count
  318.          push  dx            ; and save it again for this row
  319.          cmp   cx,cs:[Cols]  ; and test to see if we are finished
  320.          jle   Bc_Cont       ; loop
  321.  
  322.          mov   cx,cs:[Col_2_Do] ; get the number of bytes to print
  323.          or    cx,cx
  324.          jz    Bc_NoP        ; skip if didn't get anything
  325.  
  326.          push  cx            ; save number to do
  327.          mov   si,Offset cs:Set_Graf ; setup for graphics
  328.          mov   cl,cs:[si]    ; get length
  329.          xor   ch,ch
  330.          inc   si            ; point past length field
  331.          call  TabPtr        ; perform the setup
  332.  
  333.          pop   cx            ; now get the real characters to do
  334.          mov   si,Offset cs:Line_Buf ; get print line pointer
  335.          call  TabPtr        ; print the line
  336.  
  337. Bc_NoP:  call  Cr_Lf
  338.  
  339.          pop   dx
  340.          add   dx,cs:[Four]  ; add to column count
  341.          cmp   dx,cs:[Rows]  ; compare to max to do
  342.  
  343.          jg    Bc_Ret        ; if fini then exit
  344.          jmp   Bc_Strt       ; else go do next row
  345.  
  346. Bc_Ret:  jmp   Return        ; restore printer and exit
  347.  
  348. ;--------------------------------------------------------------------
  349. ;
  350. ;        Read Dot Routine Using DOS/BIOS or VDI interface for int 10h
  351. ;
  352. ;-------------------------------------------------------------------
  353. Read:     xor  al,al
  354.           cmp   dx,0          ; see if all is ok
  355.           jl    Read_Ret
  356.           cmp   cx,cs:[Cols]  ; also check on overdoing it
  357.           jg    Read_Ret
  358.           cmp   cs:[Mode],10h
  359.           je    Read_Dot      ; if mode = 10 then do special I/O
  360.           mov   ah,13
  361.           push  bx
  362.           push  cx
  363.           push  dx
  364.           int   10h
  365.           pop   dx
  366.           pop   cx
  367.           pop   bx
  368.           xor   ah,ah         ; clear the high byte for testing
  369. Read_Ret: ret
  370.  
  371. ;---------------------------------------------------------------
  372. ;
  373. ;        Read a Pixel (Dot) from the EGA using Read Mode 0
  374. ;
  375. ;----------------------------------------------------------------
  376.  
  377. Read_Dot: push bx
  378.          push  cx
  379.          push  dx
  380.          mov   ax,dx         ; save column value
  381.          mov   bx,cx         ; and row value
  382.          mov   dx,0a000h     ; Video ram address
  383.          mov   ds,dx         ; into segment register
  384.          mov   dx,80
  385.          mul   dx            ; column * 80
  386.          shr   bx,1
  387.          shr   bx,1
  388.          shr   bx,1          ; row / 8
  389.          add   bx,ax         ; actual data byte address
  390.          and   cl,7          ; row mod 8
  391.          xor   cl,7          ; bit mask 7 - (row mod 8)
  392.          mov   ch,1
  393.          shl   ch,cl         ; 2^mask
  394.          mov   ah,3          ; initialize bit plane number
  395. Plane_Loop:
  396.          mov   dx,03CEh      ; EGA Controller
  397.          mov   al,4          ; map select register
  398.          out   dx,al
  399.          mov   dx,03CFh      ; data register
  400.          mov   al,ah         ; select bit planes 3,2,1,0
  401.          out   dx,al
  402.          mov   al,ds:[bx]    ; read bit plane
  403.          shl   cl,1
  404.          and   al,ch
  405.          jz    Not_On
  406.          or    cl,1
  407. Not_On:  dec   ah
  408.          jge   Plane_Loop
  409.          and   cl,0fh
  410.          mov   al,cl
  411.          pop   dx
  412.          pop   cx
  413.          pop   bx
  414.          ret
  415.          dw    -1            ; fense
  416.          
  417. ;--------------------------------------------------------------------
  418. ;
  419. ;        Initialization Routine for Graphics.Com
  420. ;
  421. ;--------------------------------------------------------------------
  422. Setup:   xor   ax,ax
  423.          mov   es,ax              ; setup to address segment zero
  424.          mov   cx,es:[0016h]      ; get current segment
  425.          mov   bx,es:[0014h]      ; and offset
  426.          mov   ds,cx              ; make that the data segment
  427.          mov   cx,cs:[Cmp_Str]    ; setup to check bytes for same
  428.          mov   si,Offset cs:mlen  ; data field "Graphic..."
  429.          mov   bx,si  
  430.  
  431. Check:   mov   ax,cs:[si]         ; get a byte in accum
  432.          cmp   ax,ds:[bx]         ; is it the same
  433.          jne   Ok                 ; no, then we are ok
  434.          inc   si                 ; otherwise, increment pointers
  435.          inc   bx                 ; to both fields
  436.          loop  Check              ; and loop for 7 checks
  437.  
  438.          mov   ax,cs
  439.          mov   ds,ax
  440.          mov   ah,09h
  441.          mov   dx,Offset Message1
  442.          int   21h
  443.          int   20h                ; if same then dont overlay but exit
  444.  
  445. Ok:      mov   bx,es:[0014h]      ; get the current offset in int vector
  446.          mov   ax,cs              ; now setup to display a message
  447.          mov   ds,ax
  448.          mov   Word Ptr dos,bx    ; and save it locally
  449.          mov   bx,es:[0016h]      ; get the segment location of item too
  450.          mov   Word Ptr dos2,bx   ; and save it also
  451.          mov   ax,cs              ; save our entry at int vector
  452.          mov   es:[0016h],ax      ; segment
  453.          mov   bx,Offset cs:Begin ; define entry point to routine
  454.          mov   es:[0014h],bx      ; offset
  455.          mov   di,Offset Field1
  456.          call  Convert            ; convert starting address
  457.          mov   di,Offset Field2
  458.          mov   bx,Offset Setup
  459.          add   bx,15              ; convert to next paragraph addr
  460.          mov   cl,4
  461.          shr   bx,cl
  462.          add   ax,bx
  463.          call  Convert            ; and the new ending address
  464.          mov   ah,09h             ; now do our message
  465.          mov   dx,Offset Message2
  466.          int   21h
  467.          mov   dx,Offset cs:Setup
  468.          int   27h                ; terminate but stay resident
  469.  
  470. Convert  proc  near
  471. ;
  472. ;        ax = number to be converted 
  473. ;        di = address of field in which to put the hex characters 
  474. ;
  475.          push  ax
  476.          push  bx
  477.          push  cx
  478.          push  dx
  479.          lea   bx,Ascii
  480.          mov   cl,4
  481.          mov   dx,ax
  482.          mov   al,ah
  483.          shr   al,cl
  484.          xlat  Ascii
  485.          mov   Byte Ptr cs:[di],al
  486.          mov   al,dh
  487.          and   al,0fh
  488.          xlat  Ascii
  489.          mov   Byte Ptr cs:[di+1],al
  490.          mov   al,dl
  491.          shr   al,cl
  492.          xlat  Ascii
  493.          mov   Byte Ptr cs:[di+2],al
  494.          mov   al,dl
  495.          and   al,0fh
  496.          xlat  Ascii
  497.          mov   Byte Ptr cs:[di+3],al
  498.          pop   dx
  499.          pop   cx
  500.          pop   bx
  501.          pop   ax
  502.          ret
  503. Convert  endp
  504. Message1 db    'EGA Graphics routine is already resident',13,10,'$'
  505. Message2 db    'EGA Graphics routine is now resident ('
  506. Field1   db    '0000-'
  507. Field2   db    '0000)',13,10,'$'
  508. Ascii    db    '0123456789abcdef'
  509. Epson    ends
  510.          end
  511.